#include <sys/types.h>
#include <unistd.h>

#include <cerrno>
#include <cstdio>
#include <cstring>
int main() {
    // ===========fork系统调用===========
    // 1. 在父子进程都有返回，父进程返回子进程pid，子进程返回0，-1创建子进程失败
    // 2. 父进程退出，子进程不影响，自动找到祖父进程作为父进程
    pid_t pid = fork();
    if (pid > 0) {  // 父进程
        printf("我是父进程pid:%d，子进程pid:%d\n", getpid(), pid);
    } else if (pid == 0) {  // 子进程
        printf("我是子进程pid:%d，父进程pid:%d\n", getpid(), getppid());
        sleep(4);
        // 父进程退出 不影响子进程
        // 子进程会自动找到祖父进程作为父进程
        printf("新的父进程pid:%d\n", getppid());

        printf("==============================\n");
        // =============exec系统调用=============
        // exec函数族有六个，函数名由以下字母组合
        // l表示参数列举，v表示用数组存放，p表示从环境变量path中找到，e表示提供自定义环境变量
        // 注意第二个参数是进程的名字，这个进程需要额外的参数就紧随其后，最后需要一个NULL表示参数结束
        char *argv[] = {"pwd", NULL};
        execvp("pwd", argv);
    } else {  // 子进程创建失败，在父进程返回-1
        fprintf(stderr, "Failed to create a new process, msg: %s",
                std::strerror(errno));
    }
}
